/*
 * ManejadorAccesoDatos.cpp
 *
 *  Created on: 10/09/2010
 *      Author: julfc
 */

#include "ManejadorAccesoDatos.h"

ManejadorAccesoDatos::ManejadorAccesoDatos() {
}

ManejadorAccesoDatos::ManejadorAccesoDatos(char* nombreArchivo,
    AbrirCrearArchivo abrirCrear) {
  switch (abrirCrear) {
  case CREAR:
    //Crea o sobreescribe el archivo .
    this->archivo = new fstream(nombreArchivo, ios_base::in | ios_base::out
        | ios_base::binary | ios_base::trunc);
    break;
  case ABRIR:
    //Solo lo abre.
    this->archivo = new fstream(nombreArchivo, ios_base::in | ios_base::out
        | ios_base::binary);
    break;
  default:
    break;
  }
}

char* ManejadorAccesoDatos::inicillizarBloque(long tam_bloque) {
  //Guardo la memoria para el bloque
  char* bloque = (char *) malloc(tam_bloque + 1);
  memset(bloque, 0, tam_bloque);
  return bloque;
}

void ManejadorAccesoDatos::escribir(char* cadena, long nroBloque) {
  //cout << "\nEntro a escribir" << endl;
  long tam_bloque = getTamanioBloques();
  Encriptador *encripta = EncipSingleton<Encriptador>::GetInstance();
  //cout << "\nEmpiezo a eencriptar" << endl;
  encripta->encriptarPosta(cadena);
  //cout << "\nTermino de encriptar" << endl;
  this->archivo->seekp(tam_bloque * nroBloque);
  this->archivo->write(cadena, tam_bloque);
}

char* ManejadorAccesoDatos::leerBloque(long nroBloque) {
  //cout << "\nEntro a leer" << endl;
  long tam_bloque = getTamanioBloques();
  char* buffer = (char*) malloc(tam_bloque + 1);
  memset(buffer, 0, tam_bloque);
  this->archivo->seekg((tam_bloque) * nroBloque);
  this->archivo->read(buffer, tam_bloque);
  Encriptador *encripta = EncipSingleton<Encriptador>::GetInstance();
  //cout << "\nEmpiezo a desencriptar" << endl;
  encripta->desencriptarPosta(buffer);
  //cout << "\nTermino de desencriptar" << endl;
  return buffer;
}

long ManejadorAccesoDatos::getCantidadBloques() {
  this->archivo->seekg(0, ios_base::end);
  int longitud = this->archivo->tellg();
  long tam_bloque = getTamanioBloques();
  int cant_bloques = longitud / tam_bloque;
  return cant_bloques;
}

long ManejadorAccesoDatos::getTamanioBloques() {
  ManejadorConfiguracion mc;
  long tam_bloques = mc.obtenerTamanioBloque() * mc.BYTES_IN_KB;
  return tam_bloques;
}

long ManejadorAccesoDatos::buscarEspacioEnBloques(long tamanio) {
  long cantBloques = getCantidadBloques();
  long nro_bloque = -1;
  bool encontrado = false;
  long i = 0;
  char* bloque;
  while (i < cantBloques && !encontrado) {
    bloque = leerBloque(i);
    char* aux = bloque;
    long espacioLibre = 0;
    //Salteo cantidad de mails en bloque.
    aux += sizeof(long);
    memcpy(&espacioLibre, aux, sizeof(long));
    //uid + tamanio del mail + mail.
    if (espacioLibre >= (tamanio + 8)) {
      encontrado = true;
      nro_bloque = i;
    }
    i++;
    free(bloque);
  }
  return nro_bloque;
}

ManejadorAccesoDatos::~ManejadorAccesoDatos() {
  //Cierra el archivo
    if (this->archivo) {
      this->archivo->close();
      delete this->archivo;
    }
}
